﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using System.Collections;
using System.ComponentModel;

namespace SPSilver.Common
{
    public abstract class List
    {

        SPList list { get; set; }
        public void Update(Item i)
        {
            if (i.PropertiesHaveChanged)
            {
                SPListItem item = list.GetItemById(i.ID);
                foreach (DictionaryEntry property in i.AfterProperties)
                {
                    item[(Guid)property.Key] = property.Value;
                }
            }
        }
    }

    public partial class Item
    {
        public SPFieldCollection fieldsCol { get; private set; }
        public int ID { get; private set; }
        public Guid UniqueId { get; private set; }
        public String Title { get; set; }
        public String Editor { get; private set; }
        public String Author { get; private set; }
        public DateTime Created { get; private set; }
        public DateTime Modified { get; private set; }
        public int Culture { get; set; }

        public enum CultureEnum { el = 1032, en };

        public Item(SPListItem i)
        {
            Culture = System.Globalization.CultureInfo.CurrentCulture.LCID;

            if (i.ListItems != null)
            {
                fieldsCol = i.ListItems.Fields;
            }
            else
            {
                fieldsCol = null;
            }
            if (i.ID > 0)
            {
                ID = i.ID;
                UniqueId = i.UniqueId;
            }
            Title = safe<String>(i, Fields.Title);
            Editor = safe<SPFieldLookupValue>(i, Fields.Editor).LookupValue;
            Author = safe<SPFieldLookupValue>(i, Fields.Author).LookupValue;
            Created = safe<DateTime>(i, Fields.Created);
            Modified = safe<DateTime>(i, Fields.Modified);
        }

        public Hashtable AfterProperties = new Hashtable();
	
        private bool _propertiesHaveChanged;
        public bool PropertiesHaveChanged
        {
            get { return _propertiesHaveChanged; }
            private set { _propertiesHaveChanged = value; }
        }
        
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName, Guid propertyGuid, object propertyValue)
        {
            _propertiesHaveChanged = true;
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
            AfterProperties.Add(propertyGuid, propertyValue.ToString());
        }

        protected T safe<T>(SPListItem item, string fieldName)
        {
            switch (typeof(T).Name)
            {
                case "String":
                    return (T)Convert.ChangeType(safeString(item, fieldName), typeof(T));
                case "SPFieldLookupValue":
                    return (T)Convert.ChangeType(safeSPFieldLookupValue(item, fieldName), typeof(T));
            }
            return default(T);
        }
        /// <summary> Επιστρέφει μια ασφαλή τιμή</summary>
        /// <param name="p">την τιμή ενός πεδίου</param>
        /// <returns>την τιμή σαν string</returns>
        private string safeString(object p)
        {
            if (p == null)
                return String.Empty;
            else
                return p.ToString();
        }

        private string safeString(SPListItem item, string fieldName)
        {
            string toReturn = String.Empty;
            try
            {
                if ((fieldsCol == null) || (fieldsCol.ContainsField(fieldName)))
                {
                        if (item[fieldName] != null)
                            toReturn = item[fieldName].ToString();
                }
            }
            catch { }
            return toReturn;
        }


        /// <summary> Επιστρέφει μια ασφαλή τιμή</summary>
        /// <param name="p">την τιμή ενός πεδίου</param>
        /// <returns>την τιμή σαν SPFieldLookupValueCollection</returns>
        private SPFieldLookupValueCollection safeSPFieldLookupValueCollection(object p)
        {
            SPFieldLookupValueCollection coll = new SPFieldLookupValueCollection();
            if (p == null)
            {
                return coll;
            }
            else
            {
                try
                {
                    coll.AddRange(new SPFieldLookupValueCollection(p.ToString()));
                }
                catch//  (Exception e)
                { }
                return coll;
            }
        }

        private SPFieldLookupValueCollection safeSPFieldLookupValueCollection(SPListItem item, string fieldName)
        {
            SPFieldLookupValueCollection result = new SPFieldLookupValueCollection();
            if ((fieldsCol == null) || (fieldsCol.ContainsField(fieldName)))
            {
                try
                {
                    if (item[fieldName] != null)
                        result.AddRange(new SPFieldLookupValueCollection(item[fieldName].ToString()));
                }
                catch { }
            }
            return result;
        }


        /// <summary> Επιστρέφει μια ασφαλή τιμή</summary>
        /// <param name="p">την τιμή ενός πεδίου</param>
        /// <returns>την τιμή σαν SPFieldLookupValue</returns>
        private SPFieldLookupValue safeSPFieldLookupValue(object p)
        {
            SPFieldLookupValue coll = new SPFieldLookupValue(0, String.Empty);
            if (p == null)
            {
                return coll;
            }
            else
            {
                try
                {
                    coll = new SPFieldLookupValue(p.ToString());
                }
                catch// (Exception e)
                { }
                return coll;
            }
        }

        private SPFieldLookupValue safeSPFieldLookupValue(SPListItem item, string fieldName)
        {
            SPFieldLookupValue result = new SPFieldLookupValue(0, String.Empty);
            try
            {
                if ((fieldsCol == null) || (fieldsCol.ContainsField(fieldName)))
                {
                        if (item[fieldName] != null)
                            result = new SPFieldLookupValue(item[fieldName].ToString());
                }
            }
            catch { }
            return result;
        }


        /// <summary> Επιστρέφει μια ασφαλή τιμή</summary>
        /// <param name="p">την τιμή ενός πεδίου</param>
        /// <returns>την τιμή σαν SPFieldLookupValue</returns>
        private DateTime safeDateTime(object p)
        {
            DateTime dt = DateTime.Now;
            if (p == null)
            {
                return dt;
            }
            else
            {
                try
                {
                    if (DateTime.TryParse(p.ToString(), out dt))
                        return dt;
                }
                catch//  (Exception e)
                { }
                return dt;
            }
        }

        private DateTime safeDateTime(SPListItem item, string fieldName)
        {
            DateTime result = DateTime.Now;
            if ((fieldsCol == null) || (fieldsCol.ContainsField(fieldName)))
            {
                try
                {
                    if (item[fieldName] != null)
                        DateTime.TryParse(item[fieldName].ToString(), out result);
                }
                catch { }
            }
            return result;
        }

        /// <summary> Επιστρέφει μια ασφαλή τιμή</summary>
        /// <param name="p">την τιμή ενός πεδίου</param>
        /// <returns>την τιμή σαν Boolean</returns>
        private Boolean safeBoolean(object p)
        {
            Boolean result = false;
            if (p != null)
                Boolean.TryParse(p.ToString(), out result);
            return result;
        }


        private Boolean safeBoolean(SPListItem item, string fieldName)
        {
            Boolean result = false;
            if ((fieldsCol == null) || (fieldsCol.ContainsField(fieldName)))
            {
                try
                {
                    if (item[fieldName] != null)
                        Boolean.TryParse(item[fieldName].ToString(), out result);
                }
                catch { }
            }
            return result;
        }


        /// <summary> Επιστρέφει μια ασφαλή τιμή</summary>
        /// <param name="p">την τιμή ενός πεδίου</param>
        /// <returns>την τιμή σαν string</returns>
        /*public string safeLink(object p)
        {
            if (p == null)
                return String.Empty;
            else
            {
                String link = String.Empty;
                try
                {
                    String[] arr = new String[2] { String.Empty, String.Empty };
                    String temp = safeString(p);
                    arr = temp.Split(new char[] { ',' });
                    link = String.Format("<a href=\"{0}\" title=\"{1}\">{1}</a>", arr[0], arr[1]);
                }
                catch// (Exception e) 
                { }
                return link;
            }
        }*/
        /// <summary> Επιστρέφει μια ασφαλή τιμή</summary>
        /// <param name="p">την τιμή ενός πεδίου</param>
        /// <returns>την τιμή σαν Int32</returns>
        /*public Int32 safeInt(SPListItem i, string fieldName)
        {
            Int32 result = 0;
            if (i!=null)
            {
                bool contains = false;
                using (SPMonitoredScope mon2 = new SPMonitoredScope("throws i.ListItems.Fields.ContainsField(fieldName)"))
                {
                    try
                    {
                        object p = i[fieldName+"-"];
                        if (p != null)
                            Int32.TryParse(p.ToString(), out result);
                    }
                    catch { }
                }
                using (SPMonitoredScope mon = new SPMonitoredScope("fake i.ListItems"))
                {
                    SPListItemCollection coll = i.ListItems;
                    // using (SPMonitoredScope mon1 = new SPMonitoredScope("fake i.ListItems.Fields"))
                    {
                        SPFieldCollection fcoll = coll.Fields;
                        // using (SPMonitoredScope mon2 = new SPMonitoredScope("fake i.ListItems.Fields.ContainsField(fieldName)"))
                        {
                            contains = fcoll.ContainsField(fieldName + "-");
                        }
                    }
                }
                using (SPMonitoredScope mon = new SPMonitoredScope("i.ListItems"))
                {
                    SPListItemCollection coll = i.ListItems;
                    // using (SPMonitoredScope mon1 = new SPMonitoredScope("i.ListItems.Fields"))
                    {
                        SPFieldCollection fcoll = coll.Fields;
                        // using (SPMonitoredScope mon2 = new SPMonitoredScope("i.ListItems.Fields.ContainsField(fieldName)"))
                        {
                            contains = fcoll.ContainsField(fieldName);
                        }
                    }
                }
                if (!contains)
                {
                    return result;
                }
                else
                {
                    try
                    {
                        object p = i[fieldName];
                        if (p != null)
                        Int32.TryParse(p.ToString(), out result);
                    }catch{}
                }
            }
            return result;
        }*/


        /// <summary> Επιστρέφει μια ασφαλή τιμή</summary>
        /// <param name="p">την τιμή ενός πεδίου</param>
        /// <returns>την τιμή σαν string</returns>
        /*public string safeLinkOnly(object p)
        {
            if (p == null)
                return String.Empty;
            else
            {
                String link = String.Empty;
                try
                {
                    String[] arr = new String[2] { String.Empty, String.Empty };
                    String temp = safeString(p);
                    arr = temp.Split(new char[] { ',' });
                    link = arr[0];
                }
                catch // (Exception e) 
                { }
                return link;
            }
        }*/


        private string safeLinkOnly(SPListItem item, string fieldName)
        {
            string result = String.Empty;
            if ((fieldsCol == null) || (fieldsCol.ContainsField(fieldName)))
            {
                try
                {
                    if (item[fieldName] != null)
                    {
                        String[] arr = new String[2] { String.Empty, String.Empty };
                        String temp = safeString(item, fieldName);
                        arr = temp.Split(new char[] { ',' });
                        result = arr[0];
                    }
                }
                catch { }
            }
            return result;
        }


        /// <summary> Επιστρέφει μια ασφαλή τιμή</summary>
        /// <param name="p">την τιμή ενός πεδίου</param>
        /// <returns>την τιμή σαν string</returns>
        /*internal string safeLinkOnly(object p)
        {
            if (p == null)
                return String.Empty;
            else
            {
                String link = String.Empty;
                try
                {
                    String[] arr = new String[2] { String.Empty, String.Empty };
                    String temp = safeString(p);
                    arr = temp.Split(new char[] { ',' });
                    link = arr[0];
                }
                catch (Exception e) { }
                return link;
            }
        }
        */
        /// <summary> Επιστρέφει μια ασφαλή τιμή</summary>
        /// <param name="p">την τιμή ενός πεδίου</param>
        /// <returns>την τιμή σαν Int32</returns>
        private Int32 safeInt32(object p)
        {
            return safeInt(p);
        }

        /// <summary> Επιστρέφει μια ασφαλή τιμή</summary>
        /// <param name="p">την τιμή ενός πεδίου</param>
        /// <returns>την τιμή σαν Int32</returns>
        private Int32 safeInt(object p)
        {
            Int32 result = 0;
            if (p != null)
                Int32.TryParse(p.ToString(), out result);
            return result;
        }
        private Int32 safeInt32(SPListItem item, string fieldName)
        { 
            return safeInt(item, fieldName);
        }

        private Int32 safeInt(SPListItem item, string fieldName)
        {
            Int32 result = 0;
            if ((fieldsCol == null) || (fieldsCol.ContainsField(fieldName)))
            {
                try
                {
                    if (item[fieldName] != null)
                        Int32.TryParse(item[fieldName].ToString(), out result);
                }
                catch { }
            }
            return result;
        }


        public class Fields
        {
            public static readonly String Editor = "Editor";
            public static readonly String Author = "Author";
            public static readonly String Created = "Created";
            public static readonly String Modified = "Modified";
            public static readonly String Title = "Title";
        }
    }
}
